﻿using System;
using System.IO;
using System.Xml;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Configuration;
using System.Activities;
using System.Activities.Core.Presentation;
using System.Activities.Presentation;
using System.Activities.Statements;
using System.Activities.Presentation.View;
using System.Reflection;
using System.ComponentModel;
using System.IO.IsolatedStorage;
using Toolbox = System.Activities.Presentation.Toolbox;
using Win32 = Microsoft.Win32;
using Entities = Vision.Core.Entities;

namespace Vision.VisionWorkshop
{
	/// <summary>
	/// 
	/// </summary>
	public partial class Workshop : Page
	{
		private delegate void UpdateUiTextDelegate(string text);
        private bool _ToolBoxLoaded = false;

		/// <summary>
		/// 
		/// </summary>
        public Workshop()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dockManager_Loaded(object sender, RoutedEventArgs e)
        {
            Common.TextboxWriter tbWriter = new Common.TextboxWriter();
            tbWriter.TextWritenEvent += delegate(string s){
                this.Dispatcher.Invoke(new UpdateUiTextDelegate(UpdateUiText), new object[] { s });
            };
            Console.SetOut(tbWriter);
                        
            //try{
            //    using (var storage = IsolatedStorageFile.GetUserStoreForApplication()){
            //        using (var isoStream = storage.OpenFile("AvalonDockLayout.xml", FileMode.OpenOrCreate)){
            //            if (isoStream.Length > 0){
            //                this.dockManager.RestoreLayout(isoStream);
            //            }                        
            //        }
            //    }
            //}
            //catch (Exception ex){
            //    this.UpdateUiText(ex.ToString());
            //}                           
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ctlToolbox_Loaded(object sender, RoutedEventArgs e)
        {
            if (!this._ToolBoxLoaded){
                System.Activities.Presentation.Toolbox.ToolboxControl toolboxControl = (System.Activities.Presentation.Toolbox.ToolboxControl)sender;
                if (toolboxControl != null){
                    toolboxControl.IsEnabled = false;

                    Common.ToolboxConfigSection toolboxConfig = (Common.ToolboxConfigSection)ConfigurationManager.GetSection("Toolbox");

                    if (toolboxConfig != null){
                        foreach (Common.ToolboxItemElement tbItem in toolboxConfig.ToolboxItems){
                            if ((from t in toolboxControl.Categories where t.CategoryName == tbItem.Group select t).Count() == 0){
                                toolboxControl.Categories.Add(new Toolbox.ToolboxCategory(tbItem.Group));
                            }

                            Toolbox.ToolboxCategory toolboxCategory = (from t in toolboxControl.Categories where t.CategoryName == tbItem.Group select t).Single();
                            if (toolboxCategory != null){
                                try{
                                    Toolbox.ToolboxItemWrapper tbItemWrapper = new Toolbox.ToolboxItemWrapper();
                                    tbItemWrapper.AssemblyName = tbItem.AssemblyName;
                                    tbItemWrapper.ToolName = tbItem.ToolName;
                                    tbItemWrapper.DisplayName = tbItem.DisplayName;
                                    toolboxCategory.Tools.Add(tbItemWrapper);
                                }
                                catch (Exception tbEx){
                                    this.UpdateUiText(tbEx.ToString());
                                }
                            }
                        }
                    }
                    toolboxControl.IsEnabled = true;
                    this._ToolBoxLoaded = true;
                }
            }
        }            

		/// <summary>
		/// 
		/// </summary>
		/// <param name="text"></param>
		public void UpdateUiText(string text)
		{
			this.txtOutput.AppendText(text);
			this.txtOutput.ScrollToEnd();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void Menu_Click(object sender, RoutedEventArgs e)
		{
			MenuItem menuItem = (MenuItem)e.Source;
			if (menuItem != null)
			{
				switch ((string)menuItem.Header)
				{
					case "_New":
						this.ActivityNew();
						break;
					case "_Open":
						this.ActivityOpen();
						break;
					case "_Save":
						this.ActivitySave();
						break;
					case "_Run":
						this.ActivityRun();
						break;
					case "_Exit":
						break;
				}
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void toolbarButton_Click(object sender, RoutedEventArgs e)
		{
			Button toolbarButton = (Button)sender;
			if (toolbarButton != null)
			{
				switch (toolbarButton.CommandParameter.ToString())
				{
					case "New":
						this.ActivityNew();
						break;
					case "Open":
						this.ActivityOpen();
						break;
					case "Save":
						this.ActivitySave();
						break;
					case "FileManager":
						this.FileManager();
						break;
					case "Scheduling":
						this.ScheduleManager();
						break;
					case "Run":
						this.ActivityRun();
						break;
				}
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void btnClearOutput_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
		{
			this.txtOutput.Text = string.Empty;
		}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="activityDesigner"></param>
        private void CreateAvalonDocumentContent(Vision.VisionWorkshop.Controls.EnterpriseActivityDesigner activityDesigner)
        {
            Binding nameBinding = new Binding();
            nameBinding.Source = activityDesigner;
            nameBinding.Path = new PropertyPath("Display");
                        
            var documentContent = new AvalonDock.DocumentContent();            
            documentContent.Content = activityDesigner;
            documentContent.SetBinding(AvalonDock.DocumentContent.NameProperty, nameBinding);
            documentContent.SetBinding(AvalonDock.DocumentContent.TitleProperty, nameBinding);
            
            // when document becomes active
            documentContent.IsActiveDocumentChanged += delegate(object sender, EventArgs e){
                if (documentContent.IsActiveDocument){
                    if (activityDesigner != null && activityDesigner.WorkflowDesigner != null){
                        ctlPropertiesWindow.Content = activityDesigner.WorkflowDesigner.PropertyInspectorView;
                    }
                }
            };

            // when document is closing
            documentContent.Closing += delegate(object sender, CancelEventArgs e){
				if (activityDesigner.IsDirty)
				{
					MessageBoxResult msgResult = MessageBox.Show("Changes have been made.  Do you want to save the changes?", "Save changes", MessageBoxButton.YesNoCancel);
					if (msgResult == MessageBoxResult.Yes)
					{
						// save the designer, then move on close the window
						ActivitySave(activityDesigner, new EventHandler<AsyncCompletedEventArgs>(delegate(object s, AsyncCompletedEventArgs args) { activityDesigner.Close(); }));
						activityDesigner.Close();
						e.Cancel = false;
					}
					else if (msgResult == MessageBoxResult.No)
					{
						// do nothing, and move on to close the window                        
						activityDesigner.Close();
						e.Cancel = false;
					}
					else
					{
						// prevent the designer from closing
						e.Cancel = true;
					}
				}
				else
				{
					activityDesigner.Close();
				}
            };
            
            documentContent.Show(this.dockManager);            
        }

		/// <summary>
		/// 
		/// </summary>
		private void ActivityNew()
		{
            Vision.VisionWorkshop.Controls.EnterpriseActivityDesigner activityDesigner = new Vision.VisionWorkshop.Controls.EnterpriseActivityDesigner();
            activityDesigner.New();
            activityDesigner.DesignerUpdateEvent += delegate(UIElement propertyWindow) { this.ctlPropertiesWindow.Content = propertyWindow; };            
            this.CreateAvalonDocumentContent(activityDesigner);
		}

		/// <summary>
		/// 
		/// </summary>
		private void ActivityOpen()
		{
            Windows.ActivityOpen wndActivityOpen = new Windows.ActivityOpen();
            wndActivityOpen.ActivitySelectedEvent += delegate(Entities.Activities.VisionActivity enterpriseActivity){
                Vision.VisionWorkshop.Controls.EnterpriseActivityDesigner activityDesigner = new Vision.VisionWorkshop.Controls.EnterpriseActivityDesigner();
                activityDesigner.Open(enterpriseActivity);
                activityDesigner.DesignerUpdateEvent += delegate(UIElement propertyWindow) { this.ctlPropertiesWindow.Content = propertyWindow; };                
                this.CreateAvalonDocumentContent(activityDesigner);
            };
            wndActivityOpen.ShowDialog();                        
		}
                                        		        		
        /// <summary>
        /// 
        /// </summary>
        private void ActivitySave()
        {
            if (this.dockManager.ActiveDocument.Content != null){
                Vision.VisionWorkshop.Controls.EnterpriseActivityDesigner entActDesigner = (Vision.VisionWorkshop.Controls.EnterpriseActivityDesigner)this.dockManager.ActiveDocument.Content;
                if (entActDesigner != null){
                    svcVision.VisionServiceClient visionClient = new svcVision.VisionServiceClient();
                    Entities.Activities.VisionActivity enterpriseActivity = entActDesigner.Save();
                    this.Cursor = Cursors.Wait;
                    entActDesigner.IsEnabled = false;
                    visionClient.SaveVisionActivityToCatalogCompleted += delegate(object sender, System.ComponentModel.AsyncCompletedEventArgs e){
                        entActDesigner.MarkAsSaved();
                        entActDesigner.IsEnabled = true;
                        this.Cursor = Cursors.Arrow;
                    };
                    visionClient.SaveVisionActivityToCatalogAsync(enterpriseActivity);   
                }
            }            
        }
        
        /// <summary>
		/// 
		/// </summary>
		private void ActivitySave(Vision.VisionWorkshop.Controls.EnterpriseActivityDesigner activityDesigner, EventHandler<AsyncCompletedEventArgs> SaveCompleted)
		{
            svcVision.VisionServiceClient visionClient = new svcVision.VisionServiceClient();

			Entities.Activities.VisionActivity enterpriseActivity = activityDesigner.Save();

			this.Cursor = Cursors.Wait;
			activityDesigner.IsEnabled = false;
			visionClient.SaveVisionActivityToCatalogCompleted += delegate(object sender, System.ComponentModel.AsyncCompletedEventArgs e){
				activityDesigner.MarkAsSaved();
				activityDesigner.IsEnabled = true;
				this.Cursor = Cursors.Arrow;

                if (SaveCompleted != null){
                    SaveCompleted(sender, e);
                }
			};
			visionClient.SaveVisionActivityToCatalogAsync(enterpriseActivity);
		}

		/// <summary>
		/// 
		/// </summary>
		private void ActivityRun()
		{
			if(this.dockManager.ActiveDocument.Content != null){
                Vision.VisionWorkshop.Controls.EnterpriseActivityDesigner entActDesigner = (Vision.VisionWorkshop.Controls.EnterpriseActivityDesigner)this.dockManager.ActiveDocument.Content;
                if (entActDesigner != null){
                    entActDesigner.Run();
                }
            }
		}

		/// <summary>
		/// 
		/// </summary>
		private void FileManager()
		{
			Windows.FileManager wndFileManager = new Windows.FileManager();
			wndFileManager.ShowDialog();
		}

		/// <summary>
		/// 
		/// </summary>
		private void ScheduleManager()
		{
			Windows.ScheduleManager wndScheduleManager = new Windows.ScheduleManager();
			wndScheduleManager.ShowDialog();
		}        
	}
}
